package com.level2app.base;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import com.dylanc.viewbinding.ViewBindingUtil;
import com.level2app.di.FragmentComponent;
import com.level2app.di.FragmentModule;
import com.level2app.di.retrofit.RetrofitHelper;
import com.level2app.view.dialog.LoadingDialog;
import com.level2app.di.DaggerFragmentComponent;

import javax.inject.Inject;

public abstract class BaseFragment<T extends ViewDataBinding, D extends BaseViewModel> extends Fragment {

    private LoadingDialog loadingDialog;
    protected T binding;
    protected D viewModel;
    protected Context mContext;
    @Inject
    RetrofitHelper retrofitHelper;
    /**
     * 是否执行懒加载
     */
    private boolean isLoaded = false;

    /**
     * 当前Fragment是否对用户可见
     */
    protected boolean isVisibleToUser = false;

    /**
     * 当使用ViewPager+Fragment形式会调用该方法时，setUserVisibleHint会优先Fragment生命周期函数调用，
     * 所以这个时候就,会导致在setUserVisibleHint方法执行时就执行了懒加载，
     * 而不是在onResume方法实际调用的时候执行懒加载。所以需要这个变量
     */
    private boolean isCallResume = false;

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        mContext = context;
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = ViewBindingUtil.inflateWithGeneric(this, getLayoutInflater(), container, false);
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        binding.setLifecycleOwner(this);
        // 绑定dagger
        initInject();
        viewModel = bindModel();
        viewModel.setRetrofitHelper(retrofitHelper);
        initLoadingDialog();
        initData();
        initCtrl();
        initClick();
    }

    protected abstract D bindModel();

    protected abstract void initInject();

    protected abstract void initData();

    protected void initCtrl() {

    }
    protected void initClick() {

    }

    protected FragmentComponent getFragmentComponent() {
        return DaggerFragmentComponent.builder().appComponent(MyApplication.getInstance().getAppComponent()).fragmentModule(new FragmentModule(this)).build();
    }

    @Override
    public void onResume() {
        super.onResume();
        isCallResume = true;
        lazyInit();
    }

    private void lazyInit() {
        if (!isLoaded && isVisibleToUser && isCallResume) {
            lazyLoadData();
            isLoaded = true;
        }
    }

    protected void lazyLoadData() {

    }

    public void initLoadingDialog() {
        if (null == loadingDialog) {
            LoadingDialog.Builder builder = new LoadingDialog.Builder(getActivity())
                    .setCancelable(false);
            loadingDialog = builder.create();
        }
    }

    public void showLoadingDialog() {
        if (null != loadingDialog) {
            loadingDialog.show();
        }
    }

    public void dismissLoadingDialog() {
        if (loadingDialog != null) {
            loadingDialog.dismiss();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onDestroyView() {
        if (binding != null) {
            binding.unbind();
        }
        if (viewModel != null) {
            viewModel.unSubscribe();
        }
        super.onDestroyView();
        isLoaded = false;
        isVisibleToUser = false;
        isCallResume = false;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (loadingDialog != null) {
            loadingDialog.dismiss();
            loadingDialog = null;
        }
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        isVisibleToUser = !hidden;
        lazyInit();
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        this.isVisibleToUser = isVisibleToUser;
        lazyInit();
    }

    public <T extends BaseViewModel> T getViewModel(Fragment activity, Class<T> cls) {
        return new ViewModelProvider(activity).get(cls);
    }
}
